package com.zb.schedule;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zb.entity.ZjWithdrawBankExchangeRedisEntity;
import com.zb.entity.ZjWithdrawRecord;
import com.zb.service.ZjWithdrawRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 银行提款操作Redis数据推入定时器<br/>
 * 每分钟10条数据
 * */
@Component
@Slf4j
public class BankExchangeRedisPushSchedule {
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private ZjWithdrawRecordService zjWithdrawRecordService;
    private final String KEY = "BANK_EXCHANGE";
    private final ObjectMapper objectMapper= new ObjectMapper();

    @Scheduled(cron = "0 0/1 * * * ?")
    public void schedule(){
//        log.info("开始执行银行提款操作Redis数据推入定时器");
        //从Redis中获取数据
        //从zj_withdraw_record表中拉取10条数据推入Redis并更改对应数据在表中的状态
        //从表中获取10条状态为未推入的数据
        List<ZjWithdrawRecord> isPush = zjWithdrawRecordService.list(new QueryWrapper<ZjWithdrawRecord>().eq("is_push",false).last("limit 10"));
//        log.info("查询结果{}",isPush);
        //一个后缀用于做记录
        String suffix = String.valueOf(System.currentTimeMillis());
        //将数据推入Redis
        isPush.forEach(zjWithdrawRecord -> {
            try{
                //构建Redis缓存实体对象
                ZjWithdrawBankExchangeRedisEntity zjWithdrawBankExchangeRedisEntity = convertRecordToRedisEntity(zjWithdrawRecord);
                //序列化为JSON字符串
                String json = objectMapper.writeValueAsString(zjWithdrawBankExchangeRedisEntity);
                //推入Redis
                stringRedisTemplate.opsForHash().put(KEY,String.valueOf(zjWithdrawRecord.getId()),json);
                stringRedisTemplate.opsForHash().put(KEY+suffix,String.valueOf(zjWithdrawRecord.getId()),json);
                stringRedisTemplate.expire(KEY+suffix,100, TimeUnit.SECONDS);
                //如果没有异常，则更新数据库对应记录推入状态
                zjWithdrawRecord.setIsPush(true);
                zjWithdrawRecord.setPushTime(LocalDateTime.now());
                zjWithdrawRecordService.updateById(zjWithdrawRecord);
                //打印日志
                log.info("Redis推入成功：{}", json);
            }catch (Exception e){
                //发生异常时，删除Redis中的数据，回滚数据表中的记录
                stringRedisTemplate.opsForHash().delete(KEY+String.valueOf(zjWithdrawRecord.getId()));
                zjWithdrawRecord.setIsPush(false);
                zjWithdrawRecord.setPushTime(null);
                zjWithdrawRecordService.updateById(zjWithdrawRecord);
                log.info("Redis发生异常：{}", e.getMessage());
            }
        });
    }

    private static ZjWithdrawBankExchangeRedisEntity convertRecordToRedisEntity(ZjWithdrawRecord zjWithdrawRecord) {
        ZjWithdrawBankExchangeRedisEntity zjWithdrawBankExchangeRedisEntity = new ZjWithdrawBankExchangeRedisEntity();
        zjWithdrawBankExchangeRedisEntity.setUserId(zjWithdrawRecord.getApplyNetworkEmpId());
        zjWithdrawBankExchangeRedisEntity.setWithdrawId(zjWithdrawRecord.getId());
        zjWithdrawBankExchangeRedisEntity.setAccount(zjWithdrawRecord.getAccount());
        zjWithdrawBankExchangeRedisEntity.setAccountName(zjWithdrawRecord.getAccountName());
        zjWithdrawBankExchangeRedisEntity.setWithdrawMoney(zjWithdrawRecord.getAmount());
        zjWithdrawBankExchangeRedisEntity.setBankName(zjWithdrawRecord.getBankName());
        zjWithdrawBankExchangeRedisEntity.setBankCode(zjWithdrawRecord.getBankCode());
        zjWithdrawBankExchangeRedisEntity.setOpenAccountBankNetwork(zjWithdrawRecord.getOpenAccountBankNetwork());
        return zjWithdrawBankExchangeRedisEntity;
    }
}
